package me.baicai.modules.quartz.task;

import cn.hutool.extra.template.Template;
import cn.hutool.extra.template.TemplateConfig;
import cn.hutool.extra.template.TemplateEngine;
import cn.hutool.extra.template.TemplateUtil;
import lombok.extern.slf4j.Slf4j;
import me.baicai.domain.vo.EmailVo;
import me.baicai.service.EmailService;
import me.baicai.weixin.conf.IdentityKey;
import me.baicai.weixin.conf.OrderKey;
import me.baicai.weixin.entity.identity.Agent;
import me.baicai.weixin.entity.identity.Shop;
import me.baicai.weixin.entity.order.Account;
import me.baicai.weixin.entity.order.MoneyLog;
import me.baicai.weixin.entity.order.Order;
import me.baicai.weixin.identity.repository.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import java.util.*;


@Slf4j
@Component
public class OrderTask
{
    private final OrderRepository orderRepository;

    private final MoneyLogRepository moneyLogRepository;

    private final AccountRepository accountRepository;

    private final ShopRepository shopRepository;

    private final AgentRepository agentRepository;

    private final EmailService emailService;


    public OrderTask(OrderRepository orderRepository,
                     MoneyLogRepository moneyLogRepository,
                     AccountRepository accountRepository,
                     ShopRepository shopRepository,
                     AgentRepository agentRepository, EmailService emailService)
    {
        this.orderRepository = orderRepository;
        this.moneyLogRepository = moneyLogRepository;
        this.accountRepository = accountRepository;
        this.shopRepository = shopRepository;
        this.agentRepository = agentRepository;
        this.emailService = emailService;
    }

    public void run()
    {
        // 获取所有未结束的订单
        List<Order> list = orderRepository.findAllByOrderstatusAndEndBeforeOrOrderstatus(
            OrderKey.进行中, new Date(), OrderKey.提前结束);

        log.info(new Date() + " 本次处理订单列表数量为 : " + list.size());

        if (null == list && list.size() == 0)
        {
            return;
        }

        // 循环列表订单进行分成
        for (Order arr : list)
        {

            float amount = arr.getAmount();
            if (amount <= 0.1)
            {
                arr.setOrderstatus(OrderKey.完成);
                arr.setEnd(new Date());
                orderRepository.save(arr);
                continue;
            }
            // 获取涉及的代理 商家 以及人员
            Shop shop = shopRepository.getById(arr.getShopid());

            /***************** 店铺相关人员 *********************/
            if (null == shop)
            {
                arr.setOrderstatus(OrderKey.完成);
                arr.setEnd(new Date());
                orderRepository.save(arr);
                continue;
            }

            // 关连人员
            if (StringUtils.isNotEmpty(shop.getEngId()) && null != shop.getEngCommission() && shop.getEngCommission() > 0)
            {
                Account account = accountRepository.findAccountByOpenid(shop.getEngId());
                float f = arr.getAmount() * shop.getEngCommission() / 100;
                account.setBalance(account.getBalance() + f);
                account.setCumulative(account.getCumulative() + f);
                accountRepository.save(account);
                this.insertMoneyLog(IdentityKey.engineer, account.getOpenid(), arr.getId(),
                    OrderKey.SEC_分成, OrderKey.TYPE_收入, f, shop.getId());
                amount -= f;
            }
            if (StringUtils.isNotEmpty(shop.getSalesmanId()) && null != shop.getSalesmanCommission() && shop.getSalesmanCommission() > 0)
            {
                Account account = accountRepository.findAccountByOpenid(shop.getSalesmanId());
                float f = arr.getAmount() * shop.getEngCommission() / 100;
                account.setBalance(account.getBalance() + f);
                account.setCumulative(account.getCumulative() + f);
                accountRepository.save(account);
                this.insertMoneyLog(IdentityKey.salesman, account.getOpenid(), arr.getId(),
                    OrderKey.SEC_分成, OrderKey.TYPE_收入, f, shop.getId());
                amount -= f;
            }

            if (StringUtils.isNotEmpty(shop.getOpenid()) && shop.getCommission() > 0)
            {
                Account account = accountRepository.findAccountByOpenid(shop.getOpenid());
                float f = arr.getAmount() * shop.getCommission() / 100;
                account.setBalance(account.getBalance() + f);
                account.setCumulative(account.getCumulative() + f);
                accountRepository.save(account);
                this.insertMoneyLog(IdentityKey.shop, account.getOpenid(), arr.getId(),
                    OrderKey.SEC_分成, OrderKey.TYPE_收入, f, shop.getId());
                amount -= f;
            }

            /******************* 代理和总部 *********************/
            Agent agent = agentRepository.findByOpenid(shop.getAgentid());
            // 判断是省代还是市代
            if (agent.getLevel() == 1)
            {
                agent.getAccount().setBalance(agent.getAccount().getBalance() + amount);
                agent.getAccount().setCumulative(agent.getAccount().getCumulative() + amount);
                accountRepository.save(agent.getAccount());
                this.insertMoneyLog(IdentityKey.agent, agent.getAccount().getOpenid(), arr.getId(),
                    OrderKey.SEC_分成, OrderKey.TYPE_收入, amount, shop.getId());
            }
            else if (agent.getLevel() == 2)
            {

                /*************** 公司 *****************/
                Account account = accountRepository.findAccountByOpenid(agent.getParent());
                float f = arr.getAmount() * (100 - agent.getCommission()) / 100;
                account.setBalance(account.getBalance() + f);
                account.setCumulative(account.getCumulative() + f);
                accountRepository.save(account);
                this.insertMoneyLog(IdentityKey.agent, account.getOpenid(), arr.getId(),
                    OrderKey.SEC_分成, OrderKey.TYPE_收入, f, shop.getId());
                amount -= f;

                /*************** 代理 *****************/
                agent.getAccount().setBalance(agent.getAccount().getBalance() + amount);
                agent.getAccount().setCumulative(agent.getAccount().getCumulative() + amount);
                accountRepository.save(agent.getAccount());
                this.insertMoneyLog(IdentityKey.agent, agent.getAccount().getOpenid(), arr.getId(),
                    OrderKey.SEC_分成, OrderKey.TYPE_收入, amount, shop.getId());
            }
            else
            {

                Agent parent = agentRepository.findByOpenid(agent.getParent());
                /*************** 公司 *****************/
                Account account = accountRepository.findAccountByOpenid(parent.getParent());
                float f = arr.getAmount() * (100 - parent.getCommission()) / 100;
                account.setBalance(account.getBalance() + f);
                account.setCumulative(account.getCumulative() + f);
                accountRepository.save(account);
                this.insertMoneyLog(IdentityKey.agent, account.getOpenid(), arr.getId(),
                    OrderKey.SEC_分成, OrderKey.TYPE_收入, f, shop.getId());
                amount -= f;

                /*************** 省代理 *****************/
                account = accountRepository.findAccountByOpenid(agent.getParent());
                f = arr.getAmount() * (parent.getCommission() - agent.getCommission()) / 100;
                account.setBalance(account.getBalance() + f);
                account.setCumulative(account.getCumulative() + f);
                accountRepository.save(account);
                this.insertMoneyLog(IdentityKey.agent, account.getOpenid(), arr.getId(),
                    OrderKey.SEC_分成, OrderKey.TYPE_收入, f, shop.getId());
                amount -= f;

                /*************** 市代理 *****************/
                agent.getAccount().setBalance(agent.getAccount().getBalance() + amount);
                agent.getAccount().setCumulative(agent.getAccount().getCumulative() + amount);
                accountRepository.save(agent.getAccount());
                this.insertMoneyLog(IdentityKey.agent, agent.getAccount().getOpenid(), arr.getId(),
                    OrderKey.SEC_分成, OrderKey.TYPE_收入, amount, shop.getId());
            }
            arr.setOrderstatus(OrderKey.完成);
            arr.setEnd(new Date());
            orderRepository.save(arr);
        }
    }

    private void insertMoneyLog(String targerType, String openid, String id, String orderSrc,
                                String moneyType, Float amount, Integer shopid)
    {
        MoneyLog moneyLog = new MoneyLog(targerType, openid, id, orderSrc, moneyType, amount,
            shopid);
        moneyLogRepository.save(moneyLog);

    }




    public void orderData(String email)
        throws Exception
    {
        Map<String,Object> map = new HashMap<>();
        map.put("weeklyOrderCount", orderRepository.findAllByWeeklyOrderCount(2));
        map.put("weeklyOrderAmount", orderRepository.findAllByWeeklyOrderAmount(2));
        map.put("weeklyOrderRefundCount", orderRepository.findAllByWeeklyOrderCount(0));
        map.put("weeklyOrderRefundAmount", orderRepository.findAllByWeeklyOrderAmount(0));
        map.put("newOrderCount", orderRepository.findAllByNowOrderCount(2));
        map.put("newOrderAmount", orderRepository.findAllByNowOrderAmount(2));
        map.put("newOrderRefundCount", orderRepository.findAllByNowOrderCount(0));
        map.put("newOrderRefundAmount", orderRepository.findAllByNowOrderAmount(0));
        EmailVo emailVo;
        String content;
        // 如果不存在有效的验证码，就创建一个新的
        TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH));
        Template template = engine.getTemplate("email/order.ftl");
        content = template.render(map);

        emailVo = new EmailVo(Arrays.asList(email.split(",")),"共城物联每日报表",content);
        emailService.send(emailVo,emailService.find());
    }





    public void closeOrder(){
        orderRepository.closeOrder();
    }
}
